home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
090
/
jck1.arc
/
JCK1.ASM
next >
Wrap
Assembly Source File
|
1985-09-23
|
12KB
|
283 lines
KB_SEG SEGMENT AT 40H ;ROM BIOS data area
ORG 1AH ;Location of keyboard buffer
KB_HEAD DW ? ;Buffer head
KB_TAIL DW ? ;Buffer tail.
KB_BUFFER DW 16 DUP (?) ;Actual keyboard buffer
KB_BUFFER_END LABEL WORD ;Two bytes past end of buffer
KB_SEG ENDS
CODE_SEG SEGMENT
TRUE = 1 ;Pseudo-Ops
FALSE = 0
ASSUME CS:CODE_SEG
ORG 100H ;A Com file
BEGIN: JMP INITIALIZE ;Skip data and Interrupt routine
COPYRIGHT DB 'Author Mark Boatright; Copyright 1985'
TST_FLG DB ?
COMMAND_KEYS DW 5400H ;SHIFT F1 300,7,E,1
DW 5500H ;SHIFT F2 300,8,N,1
DW 5600H ;SHIFT F3 1200,7,E,1
DW 5700H ;SHIFT F4 1200,8,N,1
DW 5800H ;SHIFT F5 2400,7,N,1
DW 5900H ;SHIFT F6 2400,8,N,1
;DATA_8250A stored in this format LSB, MSB, and a byte for parity,length and
;stopbit
DATA_8250A DB 75H,01H,1AH ;300,E,7,1
DB 75H,01H,07H ;300,N,8,1
DB 5DH,00H,1AH ;1200,E,7,1
DB 5DH,00H,07H ;1200,N,8,1
DB 2FH,00H,1AH ;2400,E,7,1
DB 2FH,00H,07H ;2400,N,8,1
MESSAGE DB 'JR Communications Kludge installed. (C) 1985 by '
DB 'Mark Boatright'
DB 0DH,0AH,'(For built in serial port, will not address internal '
DB 'modem.)'
DB 0DH,0AH
DB 0DH,0AH,' COMMANDS'
DB 0DH,0AH
DB 0DH,0AH,'SHIFT F1 300,E,7,1 SHIFT F2 300,N,8,1'
DB 0DH,0AH,'SHIFT F3 1200,E,7,1 SHIFT F4 1200,N,8,1'
DB 0DH,0AH,'SHIFT F5 2400,E,7,1 SHIFT F6 2400,N,8,1'
DB 0DH,0AH
DB 0DH,0AH,' INSTRUCTIONS'
DB 0DH,0AH
DB 0DH,0AH,'1. Load Communications Program.'
DB 0DH,0AH,'2. Use one of the kludge commands to set your comm parms.'
DB 0DH,0AH
DB 0DH,0AH,'NOTE: You may need to set comm parms with the '
DB 'communications program first, '
DB 0DH,0AH,' then use kludge.'
DB 0DH,0AH
DB 0DH,0AH,'NOTE: A few programs (most do not) address built in port '
DB 'as COM2.'
DB 0DH,0AH,' In that event adjust program defalts accordingly'
DB 0DH,0AH
DB 0DH,0AH,'NOTE: This version of kludge will not help with dialing '
DB 'directory problems.'
DB 0DH,0AH,' Dial from keyboard.'
DB 0DH,0AH
DB 0DH,0AH,'EXPERIMENT. GOOD LUCK!!'
DB 0H
ROM_KB_INT_9 DD 1 ;Should be location of ROM INT 9
;routine
RESIDENT_MAINLINE PROC NEAR ;OK, someone's pressed a key.
PUSH DS ;Save what we use
PUSH SI
PUSH DX
PUSH CX
PUSH BX
PUSH AX
PUSHF ;For ROM_KB_INT_9 IRET
;IRET will pop them off stack.
CALL ROM_KB_INT_9 ;Put the key in buffer
ASSUME DS:KB_SEG ;We need data from this segment
MOV AX,KB_SEG
MOV DS,AX
CALL FIND_CHAR ;find char in buffer, if any
CMP TST_FLG,TRUE ;if char valid TST_FLG returns true
JNE EXIT_MAINLINE ;Not true, we leave
CALL KEY_CHECK ;Is the character a command key?
CMP TST_FLG,TRUE ;Result of check in TST_FLG
JNE EXIT_MAINLINE ;If not a command then exit
CLI ;Shucks, JR keyboard is NMI, oh well
CALL LOOK_UP ;Where's the data for the command?
CALL BYTES_OUT ;Reset 8250A to proper JR parms
EXIT_MAINLINE:
POP AX ;restore registers
POP BX
POP CX
POP DX
POP SI
POP DS
STI
IRET ;return for terminate but stay resident
RESIDENT_MAINLINE ENDP
FIND_CHAR PROC NEAR
;On exit BX should point to character
MOV TST_FLG,FALSE
MOV BX,KB_TAIL
CMP BX,KB_HEAD ;HEAD=TAIL then no valid character
JNE VALID_CHAR
RET ;and we return with TST_FLG=FALSE
VALID_CHAR:
MOV TST_FLG,TRUE ;We know we've got a character
SUB BX,2 ;Try and move back a couple of bytes
;from kb_tail, if we're still in the
;buffer this will be location of char.
CMP BX,OFFSET KB_BUFFER ;Are we still in the buffer?
JB WRAP ;No, we'd better wrap
RET ;We're OK, let's go back
WRAP:
MOV BX,OFFSET KB_BUFFER_END ;Wrap around the buffer queue
SUB BX,2
RET ;We're OK now, let's return
FIND_CHAR ENDP
KEY_CHECK PROC NEAR
;On entry BX points to character in buffer.
;On exit TST_FLG returns status of check (true/false).
;If TST_FLG true, then CX contains the number of the command.
MOV TST_FLG,FALSE ;Assume char not a command key
MOV AX,[BX] ;Put the character in AX
LEA SI,COMMAND_KEYS ;Put starting address in SI
MOV CX,6 ;Put no. of command keys in CX
CHECK:
CMP AX,CS:[SI] ;Is char a command key?
JE MATCH ;Yes, jump out.
ADD SI,2 ;Address of next command key
LOOP CHECK ;Do it again
RET ;No Match found.
MATCH: ;OK, we've got a match.
MOV TST_FLG,TRUE ;So Resident_Mainline knows we found
;match
MOV KB_TAIL,BX ;Since it's a command key we'll take
;this character out of buffer
NEG CX ;This gives us relative positioh
ADD CX,6 ;of command key... in CX.
RET
KEY_CHECK ENDP
LOOK_UP PROC NEAR
;On entry CX contains no.(relative to position) of command
;On exit SI has starting address of relevant 8250A data
MOV AX,CX ;Put no. of command in AX
MOV CX,3 ;And multiply it by number of
MUL CL ;bytes in 8250A_DATA/no. of
;command keys. This = 3.
LEA SI,DATA_8250A ;Starting address in SI
ADD SI,AX ;Starting address of data we want
RET ;We've got our address
LOOK_UP ENDP
BYTES_OUT PROC NEAR
;For better understanding of what this routine does see the JR Tech Ref
;section on the serial port.
;On entry SI should contain the starting adress of data (DATA_8250A).
;Data arranged in this format
;1. a byte for MSB of baud rate divisor
;2. a byte for LSB of baud rate divisor
;3. a byte to set other comm parms--stopbit, wordlength, parity
MOV DX,2FBH ;Line Control register address
MOV AL,10000000B ;Must set DLAB (Divisor Latch Address
;Byte) high. Bit 7 = 1.
OUT DX,AL ;to access divisor latches LSB and MSB
JMP SHORT KT1 ;As per JR Tech Ref... We stick in
;these jumps to avoid back to back
;I/0 operations to 8250A and accomodate
;the 8250A read/write cycle time.
KT1: MOV DX,2F8H ;Address baud rate divisor LSB
MOV AX,CS:[SI] ;The LSB
OUT DX,AL
JMP SHORT KT2 ;Kill time.
KT2: INC SI ;To next byte of data
MOV DX,2F9H ;Address baud rate divisor, MSB
MOV AX,CS:[SI] ;The MSB
OUT DX,AL
JMP SHORT KT3 ;Kill time.
KT3: INC SI ;To next byte of data
MOV DX,2FBH ;Address line control register
MOV AX,CS:[SI] ;The other Comm parms
OUT DX,AL ;DLAB should now be low again.
JMP SHORT KT4 ;Kill time.
KT4: MOV DX,2F8H ;As per JR Tech Ref, writing to
;line control register may have
IN AL,DX ;caused data ready to go high
RET ;don't want to forget this
BYTES_OUT ENDP
INITIALIZE PROC NEAR
CALL GET_VECTOR
CALL INSTALL_VECTOR
CALL CLEAR_BUFFER
CALL MESSAGE_OUT
MOV DX,OFFSET INITIALIZE ;for terminate/stay resident
INT 27H ;Terminate/stay resident
INITIALIZE ENDP
GET_VECTOR PROC NEAR
;We'll use DOS function 35H, vector received in ES:BX pair
MOV AL,9H ;we want vector for interrupt 9
MOV AH,35H ;For DOS get interrupt vector function
INT 21H ;invoke the function
MOV WORD PTR ROM_KB_INT_9,BX
MOV WORD PTR ROM_KB_INT_9[2],ES
RET
GET_VECTOR ENDP
INSTALL_VECTOR PROC NEAR
ASSUME DS:CODE_SEG ;for function 25H
PUSH CS ;We send out vector we want
POP DS ;to install in DS:DX pair
MOV DX, OFFSET RESIDENT_MAINLINE
CLI
MOV AH,25H ;Use DOS function 25H to make
MOV AL,9H ;INT 9 vector point to our
INT 21H ;routine.
STI
RET
INSTALL_VECTOR ENDP
CLEAR_BUFFER PROC NEAR ;clears the keyboard buffer
ASSUME DS:KB_SEG
MOV AX,KB_SEG
MOV DS,AX
MOV BX,OFFSET KB_BUFFER ;Head and Tail set equal to
MOV KB_HEAD,BX ;first byte of buffer.
MOV KB_TAIL,BX ;Head = Tail so buffer cleared
RET
CLEAR_BUFFER ENDP
MESSAGE_OUT PROC NEAR
ASSUME DS:CODE_SEG
PUSH CS
POP DS
LEA SI,MESSAGE
MOV AH,2 ;For Dos Standard Output function
MESS_OUT:
MOV DL,[SI] ;Get a byte
CMP DL,0 ;Done?
JE MESS_OUT_DONE ;YES, jump out of loop.
INT 21H ;No, send out the byte
INC SI ;Point SI at next byte
JMP MESS_OUT ;Do it again
MESS_OUT_DONE:
RET
MESSAGE_OUT ENDP
CODE_SEG ENDS
END BEGIN ;Tell Dos where to start when it
;loads program.